package com.jic.market.impl.rest.discountamount.processor;

import com.jic.market.common.util.Money;
import com.jic.market.entity.DiscountPromotionDetail;
import com.jic.market.entity.PromotionLimitRuleEntity;
import com.jic.market.entity.PromotionRuleEntity;
import com.jic.market.enums.DiscountDetailStatusEnum;
import com.jic.market.impl.rest.discountamount.model.PromotionAmountModel;
import com.jic.market.impl.rest.discountamount.po.GoodsPo;
import com.jic.market.mapper.DiscountPromotionDetailMapper;
import com.jic.market.mapper.PromotionLimitRuleEntityMapper;
import com.jic.market.service.rest.discountamount.DiscountAmountModelService;
import org.springframework.beans.factory.annotation.Autowired;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

/**
 * @author yinhaijun
 * @date: 2020/4/9
 */
public abstract class AmountProcessor {

    @Autowired
    private PromotionLimitRuleEntityMapper promotionLimitRuleEntityMapper;

    @Autowired
    private DiscountAmountModelService discountAmountModelService;
    @Autowired
    private DiscountPromotionDetailMapper discountPromotionDetailMapper;

    public void shoppingQuery(PromotionAmountModel promotionAmountModel, GoodsPo goodsPo, String thirdUserId, Object request){
        query(promotionAmountModel, goodsPo, thirdUserId, request);
    }

    public void query(PromotionAmountModel promotionAmountModel, GoodsPo goodsPo, String thirdUserId, Object request){
        Boolean isCondition = isCondition(promotionAmountModel, goodsPo, thirdUserId);
        // 不符合优惠条件的
        if (!isCondition) {
            promotionAmountModel.fillNoDiscount(goodsPo);
            return;
        }

        // 符合优惠条件的，并且优惠总金额在0~商品总额之间的，按正常优惠走，否则，一律视为不优惠
        BigDecimal promotionDiscountTotalAmount = promotionDiscountTotalAmount(promotionAmountModel, goodsPo, request);
//        if(null != promotionDiscountTotalAmount && promotionDiscountTotalAmount.compareTo(BigDecimal.ZERO) == 1
//                && promotionDiscountTotalAmount.compareTo(goodsPo.getTotalAmount()) == -1){
        if(null != promotionDiscountTotalAmount && promotionDiscountTotalAmount.compareTo(BigDecimal.ZERO) == 1){
            promotionAmountModel.fillModelByPromotionDiscountTotalAmount(promotionDiscountTotalAmount, goodsPo);
        }else {
            promotionAmountModel.fillNoDiscount(goodsPo);
        }

    }

    public void create(PromotionAmountModel promotionAmountModel, GoodsPo goodsPo, String thirdUserId, Object request){
        query(promotionAmountModel, goodsPo, thirdUserId, request);
        promotionAmountModel.setDiscountDetailStatus(DiscountDetailStatusEnum.CREATE);
        createAfter(promotionAmountModel, request);
    }

    /** 创建后需要做的事情，钩子方法，子类自行覆盖 */
    public void createAfter(PromotionAmountModel promotionAmountModel, Object request){

    }

    /** 付款，此方法暂时不许被覆盖 */
    public final void pay(PromotionAmountModel promotionAmountModel){
        promotionAmountModel.setDiscountDetailStatus(DiscountDetailStatusEnum.PAY);
    }

    /** 退款的情况较为复杂 */
    public void refund(PromotionAmountModel promotionAmountModel, String orderNo, Object request){
        if(DiscountDetailStatusEnum.CREATE == promotionAmountModel.getDiscountDetailStatus()){
            promotionAmountModel.setDiscountDetailStatus(DiscountDetailStatusEnum.REFUND);
        }
        else if(DiscountDetailStatusEnum.PAY == promotionAmountModel.getDiscountDetailStatus()){
            // 查询同一个活动下其它商品的退款选项，如果没有其它商品或者它们都处于部分退款状态，则
            boolean isAllRefund = true;
            DiscountPromotionDetail discountPromotionDetailQ = new DiscountPromotionDetail();
            discountPromotionDetailQ.setPromotionId(promotionAmountModel.getPromotionId());
            discountPromotionDetailQ.setOrderNo(orderNo);
            List<DiscountPromotionDetail> discountPromotionDetailList = discountPromotionDetailMapper.query(discountPromotionDetailQ);
            for(DiscountPromotionDetail discountPromotionDetail : discountPromotionDetailList){
                if(!discountPromotionDetail.getId().equals(promotionAmountModel.getId())){
                    if(!DiscountDetailStatusEnum.REFUNDING.getCode().equals(discountPromotionDetail.getDiscountDetailStatus())){
                        isAllRefund = false;
                    }
                }
            }

            if(isAllRefund){
                promotionAmountModel.setDiscountDetailStatus(DiscountDetailStatusEnum.REFUND);
                // 改变其它部分退的状态为全部退
                for(DiscountPromotionDetail discountPromotionDetail : discountPromotionDetailList){
                    if(!discountPromotionDetail.getId().equals(promotionAmountModel.getId())){
                        discountPromotionDetail.setDiscountDetailStatus(DiscountDetailStatusEnum.REFUND.getCode());
                        discountPromotionDetail.setUpdateTime(new Date());
                        discountPromotionDetailMapper.update(discountPromotionDetail);
                    }
                }
            }else {
                promotionAmountModel.setDiscountDetailStatus(DiscountDetailStatusEnum.REFUNDING);
            }
        }
        refundAfter(promotionAmountModel, request);
    }

    /** 退款后需要做的事情，如优惠劵需要把优惠劵退回 */
    public void refundAfter(PromotionAmountModel promotionAmountModel, Object request){
    }

    protected Boolean checkCommonLimitRule(String promotionId, Long skuId, Long num, String thirdUserId){
        boolean checkChannelStoreLimit = true;
        boolean checkChannelIndividualLimit = true;
        PromotionLimitRuleEntity promotionLimitRuleEntity = promotionLimitRuleEntityMapper.getEntityByPromotionIdAndMpId(Long.parseLong(promotionId), skuId);
        if(null != promotionLimitRuleEntity){
            // 单渠道门店限制
            Long channelStoreLimit = promotionLimitRuleEntity.getChannelStoreLimit();
            Integer countNum = discountAmountModelService.countNum(promotionId, skuId);
            if(null != channelStoreLimit && null != channelStoreLimit && null != countNum){
                checkChannelStoreLimit = channelStoreLimit > countNum + num;
            }
            // 单渠道个人限制
            Long channelIndividualLimit = promotionLimitRuleEntity.getChannelIndividualLimit();
            Integer userCountNum = discountAmountModelService.countNum(promotionId, skuId, thirdUserId);
            if(null != channelStoreLimit && null != channelStoreLimit && null != userCountNum){
                checkChannelIndividualLimit = channelIndividualLimit > userCountNum + num;
            }
        }
        return checkChannelStoreLimit && checkChannelIndividualLimit;
    }

//    protected BigDecimal getFlightContentValue(Boolean overlayAppFlag, Integer overlayAppNum, BigDecimal condition, List<PromotionRuleEntity> promotionRuleEntityList, Integer type) {
//    }


    /**
     * 获取匹配成功的那条规则
     * @param condition 传入的条件，比如额度、数量
     * @param promotionRuleEntityList 条件规则
     * @return
     */
    protected PromotionRuleEntity getFlightPromotionRuleEntity(BigDecimal condition, List<PromotionRuleEntity> promotionRuleEntityList) {
        if(null != promotionRuleEntityList && !promotionRuleEntityList.isEmpty()){
            PromotionRuleEntity promotionRuleEntity = null;
            Integer level = -1;
            for(int i = 0; i<promotionRuleEntityList.size();i++){
                Long conditionValue = promotionRuleEntityList.get(i).getConditionValue();
                if(promotionRuleEntityList.get(i).getLevel() > level && condition.compareTo(new BigDecimal(conditionValue)) != -1){
                    promotionRuleEntity = promotionRuleEntityList.get(i);
                    level = promotionRuleEntityList.get(i).getLevel();
                }
            }
            return promotionRuleEntity;

        }
        return null;
    }

    /**
     * @param promotionRuleEntity
     * @param condition
     * @param maxMult
     * @param type 1代表金额或者数量，2代表折扣
     * @return
     */
    private BigDecimal pipei(PromotionRuleEntity promotionRuleEntity, BigDecimal condition, Integer maxMult, Integer type){
        if(condition == null || maxMult == null || condition.compareTo(BigDecimal.ZERO) == 0 || maxMult.equals(0)){
            return BigDecimal.ZERO;
        }
        Long conditionValue = promotionRuleEntity.getConditionValue();
        BigDecimal contentValue = promotionRuleEntity.getContentValue();
        if(conditionValue == null || contentValue == null || conditionValue.equals(0) || contentValue.equals(0)){
            return BigDecimal.ZERO;
        }
        if(condition.compareTo(new BigDecimal(conditionValue)) != -1){
            BigDecimal divideInt = Money.divideInt(condition, new BigDecimal(conditionValue));
            if(divideInt.compareTo(new BigDecimal(maxMult)) == 1){
                divideInt = new BigDecimal(maxMult);
            }
            if(type.equals(1)){
                return Money.multiply(contentValue, divideInt);
            }else {
                return new BigDecimal(conditionValue);
            }
        }else {
            return BigDecimal.ZERO;
        }
    }

    protected BigDecimal getFlightContentValue(Boolean overlayAppFlag, Integer overlayAppNum, BigDecimal condition, List<PromotionRuleEntity> promotionRuleEntityList, Integer type) {
        if(null == overlayAppFlag){
            return BigDecimal.ZERO;
        }
        if(null != promotionRuleEntityList && !promotionRuleEntityList.isEmpty()){
            // 超量，按匹配最高层级享受优惠
            if(!overlayAppFlag){
                BigDecimal newContentValue = null;
                Integer level = null;
                for(int i = 0; i<promotionRuleEntityList.size();i++){
                    BigDecimal newConditionValueResult = pipei(promotionRuleEntityList.get(i), condition, 1, type);
                    if(i==0){
                        newContentValue = newConditionValueResult;
                        level = promotionRuleEntityList.get(i).getLevel();
                    }else if(promotionRuleEntityList.get(i).getLevel() > level && null != newConditionValueResult){
                        newContentValue = newConditionValueResult;
                        level = promotionRuleEntityList.get(i).getLevel();
                    }
                }
                return newContentValue;
            }
            // 倍量，取第一条，然后按上限次数进行设置，比如满200送10元，上限为3，那么我买1000元的东西应该送30元
            // 如果是折扣，则不变
            else {
                PromotionRuleEntity promotionRuleEntity = promotionRuleEntityList.get(0);
                BigDecimal newContentValue = pipei(promotionRuleEntity, condition, overlayAppNum,type);
                return newContentValue;
            }
        }
        return BigDecimal.ZERO;
    }


    /** 是否符合优惠条件 */
    protected abstract Boolean isCondition(PromotionAmountModel promotionAmountModel, GoodsPo goodsPo, String thirdUserId);

    /** 优惠总额 */
    protected abstract BigDecimal promotionDiscountTotalAmount(PromotionAmountModel promotionAmountModel, GoodsPo goodsPo, Object request);

}
